<template>
  <div id="cesiumContainer"></div>
</template>

<script>
import AQI_POINT_ARRAY from "@/assets/AQI.json";
import Consts from "@/consts.js";
import util from "util";
require("cesium/Widgets/widgets.css");
// h337, Cesium are all available
const CesiumHeatmap = require("cesium-heatmap");
const HM_MIN_OPACITY = 0.11;
const HM_MAX_OPACITY = 0.35;
const HM_MIN_VALUE = 0;
const HM_MAX_VALUE = 100;

export default {
  data() {
    return {
      // aqiData: AQI_POINT_ARRAY,
      Consts: Consts,
      viewer: undefined,
			initiating: true,
      // Defining the area's boundaries (corners)
      extent: {
        west: 95.0,
        south: 24.0,
        east: 130.141964,
        north: 36.141964
        // west: xmin - .3,
        // south: ymin - .3,
        // east: xmax + .3,
        // north: ymax + .3
        // xmin=97,ymin=24,xmax=109.675,ymax=36.675
        // xmin=101.278666,xmax=107.527700,ymin=101.278666,ymax=107.527700
        // xmin=97.000000,xmax=109.941964,ymin=24.000000,ymax=36.941964
      },

      aqiLevelMap: new Map([
        [
          Consts.AQI_DATABUF_NAME.AQI_0_50,
          {
            pointArray: [],
            colorPair: [Consts.AQI_COLOR_MAP.AQI50, Consts.AQI_COLOR_MAP.AQI50]
          }
        ],
        [
          Consts.AQI_DATABUF_NAME.AQI_50_100,
          {
            pointArray: [],
            colorPair: [Consts.AQI_COLOR_MAP.AQI50, Consts.AQI_COLOR_MAP.AQI100]
          }
        ],
        [
          Consts.AQI_DATABUF_NAME.AQI_100_150,
          {
            pointArray: [],
            colorPair: [Consts.AQI_COLOR_MAP.AQI100, Consts.AQI_COLOR_MAP.AQI150]
          }
        ],
        [
          Consts.AQI_DATABUF_NAME.AQI_150_200,
          {
            pointArray: [],
            colorPair: [Consts.AQI_COLOR_MAP.AQI150, Consts.AQI_COLOR_MAP.AQI200]
          }
        ],
        [
          Consts.AQI_DATABUF_NAME.AQI_200_300,
          {
            pointArray: [],
            colorPair: [Consts.AQI_COLOR_MAP.AQI200, Consts.AQI_COLOR_MAP.AQI300]
          }
        ],
        [
          Consts.AQI_DATABUF_NAME.AQI_300_500,
          {
            pointArray: [],
            colorPair: [Consts.AQI_COLOR_MAP.AQI300, Consts.AQI_COLOR_MAP.AQI500]
          }
        ],
        [
          Consts.AQI_DATABUF_NAME.AQI_500_,
          {
            pointArray: [],
            colorPair: [Consts.AQI_COLOR_MAP.AQI500, Consts.AQI_COLOR_MAP.AQI500]
          }
        ]
      ])
    };
  },
  created() {
    var ts0 = new Date().getTime();

    this.initAQIData(AQI_POINT_ARRAY);
    var ts1 = new Date().getTime();
    console.log(util.format("initAQIData..%sms", ts1 - ts0));
  },
  mounted() {
    var ts0 = new Date().getTime();
    this.viewer = this.initViewer();
    var ts1 = new Date().getTime();
    console.log(util.format("initViewer..%sms", ts1 - ts0));
    this.createHeatMaps();
    var ts2 = new Date().getTime();
    console.log(util.format("rendering..%sms", ts2 - ts1));
    // fly to the heatmap
    this.viewer.flyTo(this.viewer.entities, {
      offset: new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-90))
    });
    var ts3 = new Date().getTime();
    console.log(util.format("flying..%sms", ts3 - ts2));

    // viewer.camera.changed.addEventListener(function() {
    //   var deg = Math.round( Cesium.Math.toDegrees(viewer.camera.heading))
    //   console.log('Heading:', deg)
    //
    //   var deg = Math.round( Cesium.Math.toDegrees(viewer.camera.pitch))
    //   console.log('Pitch:', deg)
    // })
		this.initiating = false;
  },
  methods: {
    initViewer() {
      // Viewer definition
      var viewer = new Cesium.Viewer("cesiumContainer", {
        // Lower left ball widget off
        animation: true,
        // Start button
        homeButton: true,
        // Base map selector widget
        baseLayerPicker: false,
        // Full screen button
        fullscreenButton: true,
        // Geocoder box
        geocoder: false,
        // Information box
        infoBox: false,
        // 设置地形服务（选择的Cesium的世界地形服务）
        terrainProvider: Cesium.createWorldTerrain(),
        // 设置图层服务（选择的Cesium的地名标签图层服务）
        imageryProvider: Cesium.createWorldImagery({
          style: Cesium.IonWorldImageryStyle.AERIAL_WITH_LABELS
        }),
        // imageryProvider: Cesium.createOpenStreetMapImageryProvider({
        //   url: 'https://a.tile.openstreetmap.org/'
        // }),
        //    imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
        //      url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
        //    }),
        // Base map
        // imageryProvider: Cesium.createOpenStreetMapImageryProvider({
        //   url: 'https://a.tile.openstreetmap.org/'
        // }),
        // Navigation help button
        navigationHelpButton: false,
        // Button to select modes 2D/2,5D/3D
        sceneModePicker: false,
        // Lower time bar widget
        timeline: true,
        // Force scene mode
        sceneMode: Cesium.SceneMode.SCENE3D,
        // Green box appears when selecting entities
        selectionIndicator: false
      });

      // Remove HDR effect of version 1.52
      viewer.scene.highDynamicRange = false;

      // 视角不转到地下
      viewer.scene.globe.depthTestAgainstTerrain = true;
      // 去除版权信息
      viewer._cesiumWidget._creditContainer.style.display = "none";

      var layers = viewer.scene.imageryLayers;
      console.log(util.format("layers..%s", layers.length));
      console.log(layers);
      layers.layerShownOrHidden.addEventListener(function() {
        console.log("layerShownOrHidden..");
      });
      for (var i = 0; i < layers.length; i++) {
        console.log(layers.get(i).show);
      }
      // too many..viewer.scene.postRender.addEventListener(function(){console.log('postRender')});
      // no one..viewer.scene.morphComplete.addEventListener(function(){console.log('morphComplete')});
      // no one..viewer.dataSources.dataSourceAdded.addEventListener(function(){console.log('dataSourceAdded')});
      // 5 times..viewer.entities.collectionChanged.addEventListener(function(){console.log('collectionChanged')});
			var self = this;
      viewer.camera.moveStart.addEventListener(function(arg1, arg2) {
        console.log(util.format("moveStart..initiating=%s,arg1=%j,arg2=%j", self.initiating, arg1, arg2));
				// 发出事件的时候，都已经是初始化完成过后了。
      });
      viewer.camera.moveEnd.addEventListener(function() {
        console.log("moveEnd");
      });

      return viewer;
    },
    getAQIDataBufName(value) {
      if (value <= 50) return Consts.AQI_DATABUF_NAME.AQI_0_50;
      else if (value > 50 && value <= 100) return Consts.AQI_DATABUF_NAME.AQI_50_100;
      else if (value > 100 && value <= 150) return Consts.AQI_DATABUF_NAME.AQI_100_150;
      else if (value > 150 && value <= 200) return Consts.AQI_DATABUF_NAME.AQI_150_200;
      else if (value > 200 && value <= 300) return Consts.AQI_DATABUF_NAME.AQI_200_300;
      else if (value > 300 && value <= 500) return Consts.AQI_DATABUF_NAME.AQI_300_500;
      else return Consts.AQI_DATABUF_NAME.AQI_500_;
    },
    createHeatMaps() {
      var self = this;
      this.aqiLevelMap.forEach(function(payload, key, map) {
        if (payload.pointArray.length > 0) self.createHeatMap0(self.viewer, self.extent, payload);
      });
    },
    initAQIData(data) {
      console.log(util.format("共计加载数据量:%s", data.length));
      var _extent = {xmin: 361, xmax: -361, ymin: 361, ymax: -361};
      for (var i = 0; i < data.length; i++) {
        var datae = data[i];
        _extent = {
          xmin: Math.min(_extent.xmin, datae.x),
          ymin: Math.min(_extent.ymin, datae.y),
          xmax: Math.max(_extent.xmax, datae.x),
          ymax: Math.max(_extent.ymax, datae.y)
        };

        // !!TODO 暂时简单把负值取绝对值使用
        if (datae.value < 0) datae.value = -datae.value;
        if (datae.value > 500) datae.value = 500;

        var point = {
          x: datae.x,
          y: datae.y,
          value: ((datae.value - HM_MIN_VALUE) * HM_MAX_VALUE) / 500
        };

        this.aqiLevelMap.get(this.getAQIDataBufName(datae.value)).pointArray.push(point);
      }

      // statistics
      this.aqiLevelMap.forEach(function(ele, key, map) {
        console.log(util.format("key=%s, pointArrayLen=%s", key, ele.pointArray.length));
      });

      console.log(util.format("!!TODO:据此设置extent..%j", _extent));
    },

    createHeatMap0(viewer, bounds, aqiBufValue) {
      if (aqiBufValue.pointArray[0].value < 0) {
        console.warn("point value < 0");
      }
      // 初始化CesiumHeatmap
      var hm = CesiumHeatmap.create(
        viewer, // 视图层
        bounds, // 矩形坐标
        {
          // heatmap相应参数
          backgroundColor: "rgba(0,0,0,0)",
          // 如何智能适应radius、区域大小、点数之间的关系？
          radius: 5,
          maxOpacity: HM_MAX_OPACITY,
          minOpacity: HM_MIN_OPACITY,
          // blur: .75,
          // custom gradient colors
          gradient: {
            // enter n keys between 0 and 1 here
            // for gradient color customization
            "0": aqiBufValue.colorPair[0],
            "1": aqiBufValue.colorPair[1]
          },
          // radius: 20,
          scaleRadius: false,
          useLocalExtrema: true
        }
      );
      hm.setWGS84Data(HM_MIN_VALUE, HM_MAX_VALUE, aqiBufValue.pointArray);
    }
  }
};
</script>

<style lang="less" scoped>
// @import "cesium/Widgets/widgets.css";
</style>
